﻿using System;
using System.Diagnostics;
using System.Windows.Forms;
using Mbs.Elements;
using Mbs.Log;
using Mbs.MessageService;
using Mbs.Modularity;
using Mbs.Windows;
using Mbs.Windows.Elements;
using Mbs.ComponentModel.Container;

namespace Mbs
{

    /// <summary>
    /// 应用程序启动类
    /// </summary>
    [Serializable]
    public class Launcher:MarshalByRefObject, ILauncher,IInitializable
    {
        private IDisposable UnSubscribeShellShow = null;

        private static readonly ILog log = LoggerManager.GetLogger(typeof(Launcher));

        static Launcher()
        {
            Application.ThreadException += (s, e) => e.Exception.RaiseException();
            Application.EnableVisualStyles();
            MsgBox.Init(WinFormMessageService.Instance);
        }

       
        [Inject]
        private IElementService ElementService;
        [Inject]
        private IModuleManager ModuleManager;
        [Inject]
        private IShellPresenter Presenter;

        /// <summary>
        /// 
        /// </summary>
        public ModuleLoadMode ModuleLoadMode { get; set; }

        public void Init()
        {

            log.Debug("begin initialize......");

            SynchronizeService.SynchronizeObject = Presenter.View;
            ElementService.Factories.RegisterFactory(new ToolStripElementFactory());

            if (ModuleLoadMode == ModuleLoadMode.ShellCreated)
                OnPresenterInitialize();
            else
            {
                SystemCommands.ShellShown.Attach(Presenter.View, "Shown");
                UnSubscribeShellShow = SystemCommands.ShellShown.Subscribe<EventArgs>((s, e) => OnPresenterInitialize());
            }

            log.Debug("end initialize......");
        }

        private void OnPresenterInitialize()
        {
            ModuleManager.Install();

            ModuleManager.Start();

            if (UnSubscribeShellShow != null)
                UnSubscribeShellShow.Dispose();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="args"></param>
        public void Run(params string[] args)
        {
            var currentProcess = Process.GetCurrentProcess();
            int startHandleCount = currentProcess.HandleCount;

            try
            {
               
                log.Debug("run shell form.");
                Application.Run(Presenter.View);
                log.Debug("unload shell form.");
                
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                ex.RaiseException();
            }

            try
            {
                ServiceLocator.Current.Dispose();
            }
            finally
            {
            }

            int stopHandleCount = currentProcess.HandleCount;

            int count = stopHandleCount - startHandleCount;
            if (count > 1)
                log.ErrorFormat("handle resource leak :{0}.",count);

            currentProcess.Kill();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override object InitializeLifetimeService()
        {
            return null;
        }
    }
}